{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# C-MTEB检索任务评测对比"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本notebook用于评测两个模型在C-MTEB检索任务上的性能：\n",
    "1. **BGE-M3** (`./bge-m3`)\n",
    "2. **BGE-Reranker-M3-Finetuned** (`./final_model`)\n",
    "\n",
    "我们将对这两个模型进行C-MTEB检索任务的评测，并可视化对比结果。\n",
    "\n",
    "**注意**: 为了节省显存，我们将依次评测每个模型，评测完成后会清理显存。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 0. 安装依赖"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple\n",
      "Requirement already satisfied: FlagEmbedding in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (1.3.5)\n",
      "Requirement already satisfied: mteb in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (1.38.48)\n",
      "Requirement already satisfied: sentence-transformers in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (5.1.0)\n",
      "Requirement already satisfied: pandas in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (2.3.2)\n",
      "Requirement already satisfied: matplotlib in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (3.10.5)\n",
      "Requirement already satisfied: seaborn in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (0.13.2)\n",
      "Requirement already satisfied: numpy in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (2.2.6)\n",
      "Requirement already satisfied: torch>=1.6.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (2.8.0)\n",
      "Requirement already satisfied: transformers>=4.44.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (4.55.4)\n",
      "Requirement already satisfied: datasets>=2.19.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (3.6.0)\n",
      "Requirement already satisfied: accelerate>=0.20.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (1.10.0)\n",
      "Requirement already satisfied: peft in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (0.17.1)\n",
      "Requirement already satisfied: ir-datasets in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (0.5.11)\n",
      "Requirement already satisfied: sentencepiece in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (0.2.1)\n",
      "Requirement already satisfied: protobuf in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from FlagEmbedding) (6.32.0)\n",
      "Requirement already satisfied: requests>=2.26.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (2.32.5)\n",
      "Requirement already satisfied: scikit_learn>=1.0.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (1.7.1)\n",
      "Requirement already satisfied: scipy>=0.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (1.15.2)\n",
      "Requirement already satisfied: typing-extensions>=4.5.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (4.14.1)\n",
      "Requirement already satisfied: tqdm>1.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (4.67.1)\n",
      "Requirement already satisfied: rich>=0.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (14.1.0)\n",
      "Requirement already satisfied: pytrec-eval-terrier>=0.5.6 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (0.5.8)\n",
      "Requirement already satisfied: pydantic>=2.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (2.11.7)\n",
      "Requirement already satisfied: eval_type_backport>=0.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (0.2.2)\n",
      "Requirement already satisfied: polars>=0.20.22 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from mteb) (1.32.3)\n",
      "Requirement already satisfied: filelock in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (3.19.1)\n",
      "Requirement already satisfied: pyarrow>=15.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (21.0.0)\n",
      "Requirement already satisfied: dill<0.3.9,>=0.3.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (0.3.8)\n",
      "Requirement already satisfied: xxhash in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (3.5.0)\n",
      "Requirement already satisfied: multiprocess<0.70.17 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (0.70.16)\n",
      "Requirement already satisfied: fsspec<=2025.3.0,>=2023.1.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (2025.3.0)\n",
      "Requirement already satisfied: huggingface-hub>=0.24.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (0.34.4)\n",
      "Requirement already satisfied: packaging in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (25.0)\n",
      "Requirement already satisfied: pyyaml>=5.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from datasets>=2.19.0->FlagEmbedding) (6.0.2)\n",
      "Requirement already satisfied: aiohttp!=4.0.0a0,!=4.0.0a1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (3.12.15)\n",
      "Requirement already satisfied: Pillow in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from sentence-transformers) (11.3.0)\n",
      "Requirement already satisfied: regex!=2019.12.17 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from transformers>=4.44.2->FlagEmbedding) (2025.7.34)\n",
      "Requirement already satisfied: tokenizers<0.22,>=0.21 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from transformers>=4.44.2->FlagEmbedding) (0.21.4)\n",
      "Requirement already satisfied: safetensors>=0.4.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from transformers>=4.44.2->FlagEmbedding) (0.6.2)\n",
      "Requirement already satisfied: hf-xet<2.0.0,>=1.1.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from huggingface-hub>=0.24.0->datasets>=2.19.0->FlagEmbedding) (1.1.8)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pandas) (2.9.0.post0)\n",
      "Requirement already satisfied: pytz>=2020.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pandas) (2025.2)\n",
      "Requirement already satisfied: tzdata>=2022.7 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pandas) (2025.2)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from matplotlib) (1.3.2)\n",
      "Requirement already satisfied: cycler>=0.10 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from matplotlib) (0.12.1)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from matplotlib) (4.59.1)\n",
      "Requirement already satisfied: kiwisolver>=1.3.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from matplotlib) (1.4.9)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from matplotlib) (3.2.3)\n",
      "Requirement already satisfied: psutil in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from accelerate>=0.20.1->FlagEmbedding) (7.0.0)\n",
      "Requirement already satisfied: aiohappyeyeballs>=2.5.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (2.6.1)\n",
      "Requirement already satisfied: aiosignal>=1.4.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (1.4.0)\n",
      "Requirement already satisfied: async-timeout<6.0,>=4.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (5.0.1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (25.3.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (1.7.0)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (6.6.4)\n",
      "Requirement already satisfied: propcache>=0.2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (0.3.2)\n",
      "Requirement already satisfied: yarl<2.0,>=1.17.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (1.20.1)\n",
      "Requirement already satisfied: idna>=2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from yarl<2.0,>=1.17.0->aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets>=2.19.0->FlagEmbedding) (3.10)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pydantic>=2.0.0->mteb) (0.7.0)\n",
      "Requirement already satisfied: pydantic-core==2.33.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pydantic>=2.0.0->mteb) (2.33.2)\n",
      "Requirement already satisfied: typing-inspection>=0.4.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from pydantic>=2.0.0->mteb) (0.4.1)\n",
      "Requirement already satisfied: six>=1.5 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\n",
      "Requirement already satisfied: charset_normalizer<4,>=2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from requests>=2.26.0->mteb) (3.4.3)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from requests>=2.26.0->mteb) (2.5.0)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from requests>=2.26.0->mteb) (2025.8.3)\n",
      "Requirement already satisfied: markdown-it-py>=2.2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from rich>=0.0.0->mteb) (4.0.0)\n",
      "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from rich>=0.0.0->mteb) (2.19.2)\n",
      "Requirement already satisfied: mdurl~=0.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from markdown-it-py>=2.2.0->rich>=0.0.0->mteb) (0.1.2)\n",
      "Requirement already satisfied: joblib>=1.2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from scikit_learn>=1.0.2->mteb) (1.5.1)\n",
      "Requirement already satisfied: threadpoolctl>=3.1.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from scikit_learn>=1.0.2->mteb) (3.6.0)\n",
      "Requirement already satisfied: sympy>=1.13.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (1.14.0)\n",
      "Requirement already satisfied: networkx in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (3.4.2)\n",
      "Requirement already satisfied: jinja2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (3.1.6)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.8.93 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.93)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.90 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.90)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.8.90 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.90)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==9.10.2.21 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (9.10.2.21)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.8.4.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.4.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.3.3.83 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (11.3.3.83)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.9.90 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (10.3.9.90)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.7.3.90 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (11.7.3.90)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.5.8.93 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.5.8.93)\n",
      "Requirement already satisfied: nvidia-cusparselt-cu12==0.7.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (0.7.1)\n",
      "Requirement already satisfied: nvidia-nccl-cu12==2.27.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (2.27.3)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.8.90 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.90)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12==12.8.93 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (12.8.93)\n",
      "Requirement already satisfied: nvidia-cufile-cu12==1.13.1.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (1.13.1.3)\n",
      "Requirement already satisfied: triton==3.4.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from torch>=1.6.0->FlagEmbedding) (3.4.0)\n",
      "Requirement already satisfied: setuptools>=40.8.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from triton==3.4.0->torch>=1.6.0->FlagEmbedding) (80.9.0)\n",
      "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from sympy>=1.13.3->torch>=1.6.0->FlagEmbedding) (1.3.0)\n",
      "Requirement already satisfied: beautifulsoup4>=4.4.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (4.13.5)\n",
      "Requirement already satisfied: inscriptis>=2.2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (2.6.0)\n",
      "Requirement already satisfied: lxml>=4.5.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (6.0.1)\n",
      "Requirement already satisfied: trec-car-tools>=2.5.4 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (2.6)\n",
      "Requirement already satisfied: lz4>=3.1.10 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (4.4.4)\n",
      "Requirement already satisfied: warc3-wet>=0.2.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (0.2.5)\n",
      "Requirement already satisfied: warc3-wet-clueweb09>=0.2.5 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (0.2.5)\n",
      "Requirement already satisfied: zlib-state>=0.1.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (0.1.9)\n",
      "Requirement already satisfied: ijson>=3.1.3 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (3.4.0)\n",
      "Requirement already satisfied: unlzw3>=0.2.1 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from ir-datasets->FlagEmbedding) (0.2.3)\n",
      "Requirement already satisfied: soupsieve>1.2 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from beautifulsoup4>=4.4.1->ir-datasets->FlagEmbedding) (2.7)\n",
      "Requirement already satisfied: cbor>=1.0.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from trec-car-tools>=2.5.4->ir-datasets->FlagEmbedding) (1.0.0)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages (from jinja2->torch>=1.6.0->FlagEmbedding) (3.0.2)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install FlagEmbedding mteb sentence-transformers pandas matplotlib seaborn numpy"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 安装必要的Python包\n\n安装评测所需的依赖包：\n- FlagEmbedding: 用于BGE模型\n- mteb: 多语言文本嵌入评测工具\n- sentence-transformers: 句子转换器库\n- pandas, matplotlib, seaborn: 数据处理和可视化",
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 导入库"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 导入所需的Python库\n\n导入数据处理、模型加载、评测和可视化所需的库，并设置中文显示和随机种子。",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/xiaoke/miniconda3/envs/train_code_embedding/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x7b0e92511af0>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "import json\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from datetime import datetime\n",
    "import mteb\n",
    "from mteb import MTEB\n",
    "from sentence_transformers import SentenceTransformer\n",
    "import torch\n",
    "import gc\n",
    "\n",
    "# 设置中文字体\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# 设置随机种子\n",
    "np.random.seed(42)\n",
    "torch.manual_seed(42)"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 定义模型路径和配置\n\n设置待评测模型的路径和配置信息，包括：\n- 原始BGE-M3模型路径\n- 微调后的BGE-M3模型路径\n- 输出结果目录",
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 定义模型路径和配置"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 定义检索任务列表\n\n选择要进行评测的C-MTEB检索任务，目前只使用T2Retrieval任务进行评测。",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BGE-M3路径: ./bge-m3\n",
      "BGE_M3_FINETUNE_PATH路径: ./models/bge-m3-finetuned/final_model\n",
      "输出目录: ./c_mteb_results\n"
     ]
    }
   ],
   "source": [
    "# 定义模型路径\n",
    "BGE_M3_PATH = \"./bge-m3\"\n",
    "BGE_M3_FINETUNE_PATH = \"./models/bge-m3-finetuned/final_model\"\n",
    "\n",
    "# 定义输出目录\n",
    "OUTPUT_DIR = \"./c_mteb_results\"\n",
    "os.makedirs(OUTPUT_DIR, exist_ok=True)\n",
    "\n",
    "# 定义模型配置\n",
    "MODEL_CONFIGS = [\n",
    "    {\n",
    "        'name': 'BGE-M3',\n",
    "        'path': BGE_M3_PATH,\n",
    "        'description': '原始BGE-M3模型'\n",
    "    },\n",
    "    {\n",
    "        'name': 'BGE-M3-Finetuned',\n",
    "        'path': BGE_M3_FINETUNE_PATH,\n",
    "        'description': '微调后的BGE-M3模型'\n",
    "    }\n",
    "]\n",
    "\n",
    "print(f\"BGE-M3路径: {BGE_M3_PATH}\")\n",
    "print(f\"BGE_M3_FINETUNE_PATH路径: {BGE_M3_FINETUNE_PATH}\")\n",
    "print(f\"输出目录: {OUTPUT_DIR}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 显存管理函数\n\n定义两个关键函数：\n1. cleanup_memory(): 清理GPU显存和系统内存\n2. load_and_evaluate_model(): 加载模型并执行评测任务",
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 定义检索任务"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 依次评测模型\n\n按顺序评测两个模型，每次评测后清理显存以避免内存溢出，最后显示评测结果摘要。",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "将要评测的检索任务数量: 1\n",
      "任务列表:\n",
      "1. T2Retrieval\n"
     ]
    }
   ],
   "source": [
    "retrieval_tasks = [\n",
    "    # 通用短文本检索任务（T2）\n",
    "    'T2Retrieval',\n",
    "    # # MS MARCO 风格的检索任务（注意：请以本地 mteb 版本支持的名称为准）\n",
    "    # 'MMarcoRetrieval',\n",
    "    # # Du 检索任务（特定领域检索数据集）\n",
    "    # 'DuRetrieval',\n",
    "    # # 与 COVID 文献相关的医学文本检索\n",
    "    # 'CovidRetrieval',\n",
    "    # # 中文医学问答/检索（CMedQA）\n",
    "    # 'CmedqaRetrieval',\n",
    "    # # 电商领域的文本检索（商品标题/描述等）\n",
    "    # 'EcomRetrieval',\n",
    "    # # 医学领域的一般检索任务\n",
    "    # 'MedicalRetrieval'\n",
    "]\n",
    "\n",
    "# 打印将要评测的任务列表（每个字符串都是 mteb.get_tasks(...) 可识别的任务标识符）\n",
    "print(f\"将要评测的检索任务数量: {len(retrieval_tasks)}\")\n",
    "print(\"任务列表:\")\n",
    "for i, task in enumerate(retrieval_tasks, 1):\n",
    "    # 说明：如果任务名在你本地 mteb 版本中不被识别，mteb.get_tasks(...) 会报错或跳过\n",
    "    print(f\"{i}. {task}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 查看评测结果\n\n查看并分析评测结果，包括各个模型的性能指标数据。",
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 显存管理函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cleanup_memory():\n",
    "    \"\"\"\n",
    "    清理显存和内存\n",
    "    \"\"\"\n",
    "    print(\"\\n正在清理显存和内存...\")\n",
    "    \n",
    "    # 强制垃圾回收\n",
    "    gc.collect()\n",
    "    \n",
    "    # 清理PyTorch缓存\n",
    "    if torch.cuda.is_available():\n",
    "        torch.cuda.empty_cache()\n",
    "        torch.cuda.ipc_collect()\n",
    "        \n",
    "        # 显示当前显存使用情况\n",
    "        allocated = torch.cuda.memory_allocated() / 1024**3\n",
    "        cached = torch.cuda.memory_reserved() / 1024**3\n",
    "        max_allocated = torch.cuda.max_memory_allocated() / 1024**3\n",
    "        \n",
    "        print(f\"当前显存使用情况:\")\n",
    "        print(f\"  已分配: {allocated:.2f} GB\")\n",
    "        print(f\"  已缓存: {cached:.2f} GB\")\n",
    "        print(f\"  峰值分配: {max_allocated:.2f} GB\")\n",
    "        \n",
    "        # 重置峰值内存统计\n",
    "        torch.cuda.reset_peak_memory_stats()\n",
    "    \n",
    "    print(\"显存清理完成！\")\n",
    "\n",
    "def load_and_evaluate_model(model_config, tasks, output_dir):\n",
    "    \"\"\"\n",
    "    加载模型并执行评测\n",
    "    \n",
    "    参数:\n",
    "        model_config: 模型配置字典\n",
    "        tasks: 任务列表\n",
    "        output_dir: 输出目录\n",
    "    \n",
    "    返回:\n",
    "        评测结果\n",
    "    \"\"\"\n",
    "    model_name = model_config['name']\n",
    "    model_path = model_config['path']\n",
    "    \n",
    "    print(f\"\\n{'='*60}\")\n",
    "    print(f\"开始评测模型: {model_name}\")\n",
    "    print(f\"模型路径: {model_path}\")\n",
    "    print(f\"{'='*60}\")\n",
    "    \n",
    "    # 加载模型\n",
    "    print(f\"正在加载模型 {model_name}...\")\n",
    "    model = SentenceTransformer(model_path)\n",
    "    print(f\"模型 {model_name} 加载完成，设备: {model.device}\")\n",
    "    \n",
    "    # 获取MTEB任务\n",
    "    print(f\"正在获取MTEB任务...\")\n",
    "    mteb_tasks = mteb.get_tasks(tasks=tasks)\n",
    "    \n",
    "    # 创建评测器\n",
    "    evaluation = MTEB(tasks=mteb_tasks)\n",
    "    \n",
    "    # 创建模型输出目录\n",
    "    model_output_dir = os.path.join(output_dir, model_name)\n",
    "    os.makedirs(model_output_dir, exist_ok=True)\n",
    "    \n",
    "    # 运行评测（使用新的encode_kwargs参数）\n",
    "    print(f\"开始评测 {model_name}...\")\n",
    "    results = evaluation.run(model, output_folder=model_output_dir, encode_kwargs={'batch_size': 16})\n",
    "    print(f\"模型 {model_name} 评测完成！\")\n",
    "    \n",
    "    return results"
   ]
  },
  {
   "cell_type": "markdown",
   "source": "### 结果可视化\n\n将评测结果转换为DataFrame格式，并使用条形图对比两个模型在不同指标上的性能表现。",
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 依次评测模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "================================================================================\n",
      "评测进度: 1/2 - BGE-M3\n",
      "================================================================================\n",
      "\n",
      "============================================================\n",
      "开始评测模型: BGE-M3\n",
      "模型路径: ./bge-m3\n",
      "============================================================\n",
      "正在加载模型 BGE-M3...\n",
      "模型 BGE-M3 加载完成，设备: cuda:0\n",
      "正在获取MTEB任务...\n",
      "开始评测 BGE-M3...\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #262626; text-decoration-color: #262626\">───────────────────────────────────────────────── </span><span style=\"font-weight: bold\">Selected tasks </span><span style=\"color: #262626; text-decoration-color: #262626\"> ─────────────────────────────────────────────────</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;235m───────────────────────────────────────────────── \u001b[0m\u001b[1mSelected tasks \u001b[0m\u001b[38;5;235m ─────────────────────────────────────────────────\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Retrieval</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mRetrieval\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">    - T2Retrieval, <span style=\"color: #626262; text-decoration-color: #626262; font-style: italic\">s2p</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "    - T2Retrieval, \u001b[3;38;5;241ms2p\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型 BGE-M3 评测完成！\n",
      "✅ 模型 BGE-M3 评测成功完成\n",
      "\n",
      "正在清理显存和内存...\n",
      "当前显存使用情况:\n",
      "  已分配: 0.00 GB\n",
      "  已缓存: 0.00 GB\n",
      "  峰值分配: 2.12 GB\n",
      "显存清理完成！\n",
      "\n",
      "================================================================================\n",
      "评测进度: 2/2 - BGE-M3-Finetuned\n",
      "================================================================================\n",
      "\n",
      "============================================================\n",
      "开始评测模型: BGE-M3-Finetuned\n",
      "模型路径: ./models/bge-m3-finetuned/final_model\n",
      "============================================================\n",
      "正在加载模型 BGE-M3-Finetuned...\n",
      "模型 BGE-M3-Finetuned 加载完成，设备: cuda:0\n",
      "正在获取MTEB任务...\n",
      "开始评测 BGE-M3-Finetuned...\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #262626; text-decoration-color: #262626\">───────────────────────────────────────────────── </span><span style=\"font-weight: bold\">Selected tasks </span><span style=\"color: #262626; text-decoration-color: #262626\"> ─────────────────────────────────────────────────</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;235m───────────────────────────────────────────────── \u001b[0m\u001b[1mSelected tasks \u001b[0m\u001b[38;5;235m ─────────────────────────────────────────────────\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Retrieval</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mRetrieval\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">    - T2Retrieval, <span style=\"color: #626262; text-decoration-color: #626262; font-style: italic\">s2p</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "    - T2Retrieval, \u001b[3;38;5;241ms2p\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Batches: 100%|██████████| 1426/1426 [00:38<00:00, 36.72it/s]\n",
      "Batches: 100%|██████████| 3125/3125 [45:45<00:00,  1.14it/s] \n",
      "Batches: 100%|██████████| 3125/3125 [44:22<00:00,  1.17it/s] \n",
      "Batches: 100%|██████████| 1163/1163 [17:08<00:00,  1.13it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型 BGE-M3-Finetuned 评测完成！\n",
      "✅ 模型 BGE-M3-Finetuned 评测成功完成\n",
      "\n",
      "正在清理显存和内存...\n",
      "当前显存使用情况:\n",
      "  已分配: 0.01 GB\n",
      "  已缓存: 0.02 GB\n",
      "  峰值分配: 16.13 GB\n",
      "显存清理完成！\n",
      "\n",
      "================================================================================\n",
      "所有模型评测完成！\n",
      "================================================================================\n",
      "\n",
      "成功评测的模型数量: 2\n",
      "  ✅ BGE-M3\n",
      "  ✅ BGE-M3-Finetuned\n"
     ]
    }
   ],
   "source": [
    "# 创建结果存储字典\n",
    "all_results = {}\n",
    "\n",
    "# 依次评测每个模型\n",
    "for i, model_config in enumerate(MODEL_CONFIGS):\n",
    "    model_name = model_config['name']\n",
    "    \n",
    "    print(f\"\\n{'='*80}\")\n",
    "    print(f\"评测进度: {i+1}/{len(MODEL_CONFIGS)} - {model_name}\")\n",
    "    print(f\"{'='*80}\")\n",
    "    \n",
    "    try:\n",
    "        # 评测当前模型\n",
    "        results = load_and_evaluate_model(model_config, retrieval_tasks, OUTPUT_DIR)\n",
    "        all_results[model_name] = results\n",
    "        \n",
    "        print(f\"✅ 模型 {model_name} 评测成功完成\")\n",
    "        \n",
    "    except Exception as e:\n",
    "        print(f\"❌ 模型 {model_name} 评测失败: {str(e)}\")\n",
    "        # 继续评测下一个模型\n",
    "        continue\n",
    "    \n",
    "    finally:\n",
    "        # 清理显存\n",
    "        cleanup_memory()\n",
    "        \n",
    "        # 等待一段时间确保清理完成\n",
    "        import time\n",
    "        time.sleep(2)\n",
    "\n",
    "print(f\"\\n{'='*80}\")\n",
    "print(\"所有模型评测完成！\")\n",
    "print(f\"{'='*80}\")\n",
    "\n",
    "# 显示评测结果摘要\n",
    "print(f\"\\n成功评测的模型数量: {len(all_results)}\")\n",
    "for model_name in all_results.keys():\n",
    "    print(f\"  ✅ {model_name}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 结果处理与分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'BGE-M3': [TaskResult(task_name=T2Retrieval, scores=...)],\n",
       " 'BGE-M3-Finetuned': [TaskResult(task_name=T2Retrieval, scores=...)]}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[TaskResult(task_name=T2Retrieval, scores=...)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_results[\"BGE-M3\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'dev': [{'ndcg_at_1': 0.87143,\n",
       "   'ndcg_at_3': 0.8298,\n",
       "   'ndcg_at_5': 0.81435,\n",
       "   'ndcg_at_10': 0.81379,\n",
       "   'ndcg_at_20': 0.83248,\n",
       "   'ndcg_at_100': 0.85351,\n",
       "   'ndcg_at_1000': 0.86222,\n",
       "   'map_at_1': 0.25966,\n",
       "   'map_at_3': 0.51367,\n",
       "   'map_at_5': 0.63147,\n",
       "   'map_at_10': 0.73118,\n",
       "   'map_at_20': 0.75843,\n",
       "   'map_at_100': 0.7678,\n",
       "   'map_at_1000': 0.76867,\n",
       "   'recall_at_1': 0.25966,\n",
       "   'recall_at_3': 0.53387,\n",
       "   'recall_at_5': 0.67093,\n",
       "   'recall_at_10': 0.8049,\n",
       "   'recall_at_20': 0.867,\n",
       "   'recall_at_100': 0.93423,\n",
       "   'recall_at_1000': 0.97837,\n",
       "   'precision_at_1': 0.87143,\n",
       "   'precision_at_3': 0.72813,\n",
       "   'precision_at_5': 0.60948,\n",
       "   'precision_at_10': 0.40631,\n",
       "   'precision_at_20': 0.22642,\n",
       "   'precision_at_100': 0.04921,\n",
       "   'precision_at_1000': 0.00513,\n",
       "   'mrr_at_1': 0.871427,\n",
       "   'mrr_at_3': 0.897905,\n",
       "   'mrr_at_5': 0.901269,\n",
       "   'mrr_at_10': 0.903088,\n",
       "   'mrr_at_20': 0.903817,\n",
       "   'mrr_at_100': 0.904201,\n",
       "   'mrr_at_1000': 0.904246,\n",
       "   'nauc_ndcg_at_1_max': 0.707445,\n",
       "   'nauc_ndcg_at_1_std': 0.417052,\n",
       "   'nauc_ndcg_at_1_diff1': 0.441602,\n",
       "   'nauc_ndcg_at_3_max': 0.595675,\n",
       "   'nauc_ndcg_at_3_std': 0.391203,\n",
       "   'nauc_ndcg_at_3_diff1': 0.144496,\n",
       "   'nauc_ndcg_at_5_max': 0.531721,\n",
       "   'nauc_ndcg_at_5_std': 0.344106,\n",
       "   'nauc_ndcg_at_5_diff1': 0.147766,\n",
       "   'nauc_ndcg_at_10_max': 0.463258,\n",
       "   'nauc_ndcg_at_10_std': 0.277574,\n",
       "   'nauc_ndcg_at_10_diff1': 0.18077,\n",
       "   'nauc_ndcg_at_20_max': 0.498695,\n",
       "   'nauc_ndcg_at_20_std': 0.321928,\n",
       "   'nauc_ndcg_at_20_diff1': 0.180564,\n",
       "   'nauc_ndcg_at_100_max': 0.545067,\n",
       "   'nauc_ndcg_at_100_std': 0.380428,\n",
       "   'nauc_ndcg_at_100_diff1': 0.183169,\n",
       "   'nauc_ndcg_at_1000_max': 0.557334,\n",
       "   'nauc_ndcg_at_1000_std': 0.384431,\n",
       "   'nauc_ndcg_at_1000_diff1': 0.187416,\n",
       "   'nauc_map_at_1_max': -0.209214,\n",
       "   'nauc_map_at_1_std': -0.330518,\n",
       "   'nauc_map_at_1_diff1': 0.485286,\n",
       "   'nauc_map_at_3_max': -0.069292,\n",
       "   'nauc_map_at_3_std': -0.26942,\n",
       "   'nauc_map_at_3_diff1': 0.353962,\n",
       "   'nauc_map_at_5_max': 0.093771,\n",
       "   'nauc_map_at_5_std': -0.141251,\n",
       "   'nauc_map_at_5_diff1': 0.285233,\n",
       "   'nauc_map_at_10_max': 0.339533,\n",
       "   'nauc_map_at_10_std': 0.12552,\n",
       "   'nauc_map_at_10_diff1': 0.179896,\n",
       "   'nauc_map_at_20_max': 0.418707,\n",
       "   'nauc_map_at_20_std': 0.23784,\n",
       "   'nauc_map_at_20_diff1': 0.149567,\n",
       "   'nauc_map_at_100_max': 0.439864,\n",
       "   'nauc_map_at_100_std': 0.268111,\n",
       "   'nauc_map_at_100_diff1': 0.144884,\n",
       "   'nauc_map_at_1000_max': 0.441003,\n",
       "   'nauc_map_at_1000_std': 0.269025,\n",
       "   'nauc_map_at_1000_diff1': 0.144865,\n",
       "   'nauc_recall_at_1_max': -0.209214,\n",
       "   'nauc_recall_at_1_std': -0.330518,\n",
       "   'nauc_recall_at_1_diff1': 0.485286,\n",
       "   'nauc_recall_at_3_max': -0.118505,\n",
       "   'nauc_recall_at_3_std': -0.29898,\n",
       "   'nauc_recall_at_3_diff1': 0.332039,\n",
       "   'nauc_recall_at_5_max': 0.009916,\n",
       "   'nauc_recall_at_5_std': -0.20389,\n",
       "   'nauc_recall_at_5_diff1': 0.272679,\n",
       "   'nauc_recall_at_10_max': 0.249027,\n",
       "   'nauc_recall_at_10_std': 0.065521,\n",
       "   'nauc_recall_at_10_diff1': 0.161789,\n",
       "   'nauc_recall_at_20_max': 0.365044,\n",
       "   'nauc_recall_at_20_std': 0.262135,\n",
       "   'nauc_recall_at_20_diff1': 0.112929,\n",
       "   'nauc_recall_at_100_max': 0.457508,\n",
       "   'nauc_recall_at_100_std': 0.46276,\n",
       "   'nauc_recall_at_100_diff1': 0.103382,\n",
       "   'nauc_recall_at_1000_max': 0.56986,\n",
       "   'nauc_recall_at_1000_std': 0.621923,\n",
       "   'nauc_recall_at_1000_diff1': 0.11606,\n",
       "   'nauc_precision_at_1_max': 0.707445,\n",
       "   'nauc_precision_at_1_std': 0.417052,\n",
       "   'nauc_precision_at_1_diff1': 0.441602,\n",
       "   'nauc_precision_at_3_max': 0.620006,\n",
       "   'nauc_precision_at_3_std': 0.515495,\n",
       "   'nauc_precision_at_3_diff1': -0.213214,\n",
       "   'nauc_precision_at_5_max': 0.579806,\n",
       "   'nauc_precision_at_5_std': 0.54977,\n",
       "   'nauc_precision_at_5_diff1': -0.271662,\n",
       "   'nauc_precision_at_10_max': 0.530548,\n",
       "   'nauc_precision_at_10_std': 0.593002,\n",
       "   'nauc_precision_at_10_diff1': -0.293077,\n",
       "   'nauc_precision_at_20_max': 0.508725,\n",
       "   'nauc_precision_at_20_std': 0.6246,\n",
       "   'nauc_precision_at_20_diff1': -0.299266,\n",
       "   'nauc_precision_at_100_max': 0.480062,\n",
       "   'nauc_precision_at_100_std': 0.624688,\n",
       "   'nauc_precision_at_100_diff1': -0.300259,\n",
       "   'nauc_precision_at_1000_max': 0.460142,\n",
       "   'nauc_precision_at_1000_std': 0.604324,\n",
       "   'nauc_precision_at_1000_diff1': -0.301815,\n",
       "   'nauc_mrr_at_1_max': 0.707445,\n",
       "   'nauc_mrr_at_1_std': 0.417052,\n",
       "   'nauc_mrr_at_1_diff1': 0.441602,\n",
       "   'nauc_mrr_at_3_max': 0.735132,\n",
       "   'nauc_mrr_at_3_std': 0.46088,\n",
       "   'nauc_mrr_at_3_diff1': 0.431414,\n",
       "   'nauc_mrr_at_5_max': 0.737385,\n",
       "   'nauc_mrr_at_5_std': 0.462826,\n",
       "   'nauc_mrr_at_5_diff1': 0.435374,\n",
       "   'nauc_mrr_at_10_max': 0.737677,\n",
       "   'nauc_mrr_at_10_std': 0.464858,\n",
       "   'nauc_mrr_at_10_diff1': 0.435014,\n",
       "   'nauc_mrr_at_20_max': 0.737083,\n",
       "   'nauc_mrr_at_20_std': 0.464599,\n",
       "   'nauc_mrr_at_20_diff1': 0.435046,\n",
       "   'nauc_mrr_at_100_max': 0.736744,\n",
       "   'nauc_mrr_at_100_std': 0.464142,\n",
       "   'nauc_mrr_at_100_diff1': 0.435108,\n",
       "   'nauc_mrr_at_1000_max': 0.736664,\n",
       "   'nauc_mrr_at_1000_std': 0.463987,\n",
       "   'nauc_mrr_at_1000_diff1': 0.435074,\n",
       "   'main_score': 0.81379,\n",
       "   'hf_subset': 'default',\n",
       "   'languages': ['cmn-Hans']}]}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_results[\"BGE-M3\"][0].scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "总共有 20 个评估指标\n",
      "指标列表：\n",
      " 1. ndcg_at_1\n",
      " 2. ndcg_at_3\n",
      " 3. ndcg_at_5\n",
      " 4. ndcg_at_10\n",
      " 5. map_at_1\n",
      " 6. map_at_3\n",
      " 7. map_at_5\n",
      " 8. map_at_10\n",
      " 9. recall_at_1\n",
      "10. recall_at_3\n",
      "11. recall_at_5\n",
      "12. recall_at_10\n",
      "13. precision_at_1\n",
      "14. precision_at_3\n",
      "15. precision_at_5\n",
      "16. precision_at_10\n",
      "17. mrr_at_1\n",
      "18. mrr_at_3\n",
      "19. mrr_at_5\n",
      "20. mrr_at_10\n"
     ]
    }
   ],
   "source": [
    "# 提取两个模型的评测结果\n",
    "scores_m3 = all_results[\"BGE-M3\"][0].scores['dev'][0]\n",
    "scores_reranker = all_results[\"BGE-M3-Finetuned\"][0].scores['dev'][0]\n",
    "\n",
    "# 完整的评估指标列表\n",
    "metrics = [\n",
    "    'ndcg_at_1', 'ndcg_at_3', 'ndcg_at_5', 'ndcg_at_10',\n",
    "    'map_at_1', 'map_at_3', 'map_at_5', 'map_at_10', \n",
    "    'recall_at_1', 'recall_at_3', 'recall_at_5', 'recall_at_10',\n",
    "    'precision_at_1', 'precision_at_3', 'precision_at_5', 'precision_at_10',\n",
    "    'mrr_at_1', 'mrr_at_3', 'mrr_at_5', 'mrr_at_10'\n",
    "]\n",
    "\n",
    "print(f\"总共有 {len(metrics)} 个评估指标\")\n",
    "print(\"指标列表：\")\n",
    "for i, metric in enumerate(metrics, 1):\n",
    "    print(f\"{i:2d}. {metric}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABW0AAAJOCAYAAADMCCWlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAos1JREFUeJzs3Xd0FOX7/vFrUyCUJNSEXqR3JChdqiAogqAg+pWuIEgRUEAUwY8NCyK9SRUhooANKaJIU5QmKqAoJfTQpAgEkty/P/hlTSD0hJ3Nvl/n5Jxkdmb2vrOZ2cm1zz7rMjMTAAAAAAAAAMAR/DxdAAAAAAAAAADgP4S2AAAAAAAAAOAghLYAAAAAAAAA4CCEtgAAAAAAAADgIIS2AAAAAAAAAOAghLYAAAAAAAAA4CCEtgAAAAAAAADgIIS2AAAAAAAAAOAghLYAAAAAAAAA4CCEtgAAALjtXC7XdX0tX75cf/75p/r166eIiAhlyZJF2bJlU40aNfTJJ59ctt8hQ4Yk2T4wMFAFChTQk08+qYMHD95UrWvWrNGQIUP0zz//3NB2hQoVUvv27W/qPlNanTp1VKdOHU+XAQAAgOsU4OkCAAAA4Ht++OGHJD//73//03fffadvv/02yfLSpUtrxowZ+uqrr/TEE0/orrvuUmxsrCIjI/XII49o6NChGjx48GX7X7RokUJDQ3X69GktWbJE7777rtasWaNNmzYpMDDwhmpds2aNhg4dqvbt2ytLlizXvd38+fMVEhJyQ/cFAAAASIS2AAAA8ICqVasm+Tlnzpzy8/O7bLkkPfroo+revbtcLpd7WePGjXXkyBENGzZM/fv3V/r06ZNsExERoRw5ckiSGjRooCNHjmjq1KlatWqV6tatmwod/efs2bPKkCGD7rzzzlS9HwAAAKRdTI8AAAAAR8uRI0eSwDbB3XffrTNnzujYsWPX3EflypUlSYcOHUqy/JtvvlH9+vUVEhKijBkzqkaNGlq2bJn79iFDhui5556TJBUuXDjJtA3SxSkQHnjgAc2bN0933nmngoKCNHToUPdtl06PcPLkSfXr10+FCxdWunTplDdvXvXu3Vv//vuve50777xTtWrVuqyHuLg45c2bVy1atHAvGzp0qKpUqaJs2bIpJCRElSpV0gcffCAzu+bvBAAAAM7FSFsAAAB4pe+++045c+ZUWFjYNdfduXOnJKl48eLuZR9++KHatm2rZs2aafr06QoMDNSECRPUqFEjLV68WPXr11fnzp117NgxjRo1SvPmzVPu3LklXZy2IcGGDRu0detWvfjiiypcuLAyZcqUbA1nzpxR7dq1tXfvXr3wwgsqX768fv/9dw0ePFi//vqrvvnmG7lcLnXo0EG9evXS9u3bVaxYMff2S5Ys0f79+9WhQwf3sl27dqlLly4qUKCAJOnHH39Ujx49tG/fvmSnjQAAAIB3ILQFAACA15k8ebKWL1+u999/X/7+/pfdHhcXp9jYWJ0+fVpLly7VuHHj1KZNG1WqVEnSxQC1V69eeuCBBzR//nz3dk2aNFGlSpX0wgsvaO3atcqXL587EL3zzjtVqFChy+4rOjpaW7ZsSRIIJ2fkyJHavHmz1q5d6x75W79+feXNm1cPP/ywFi1apMaNG+vxxx/Xc889p2nTpum1115zbz9t2jSFh4ercePG7mVTp051fx8fH686derIzPT+++/rpZdeSnaEMgAAAJyP6REAAADgVb7++mt1795dDz/8sHr06JHsOrly5VJgYKCyZs2qVq1aKSIiQtOnT3ffvmbNGh07dkzt2rVTbGys+ys+Pl733Xeffv755yRTFlxN+fLlrxnYStKXX36psmXLqmLFiknus1GjRkmmXMiePbuaNm2q6dOnKz4+XpJ0/PhxffbZZ2rbtq0CAv4bd/Htt9+qQYMGCg0Nlb+/vwIDAzV48GAdPXpU0dHR11U/AAAAnIfQFgAAAF5j8eLFatGihe69917NmjXriiNJv/nmG/38889avHixWrZsqRUrViQJeBPmtn344YcVGBiY5GvYsGEys+uaK1eSe8qEazl06JA2b9582f0FBwfLzHTkyBH3uh07dtS+ffu0dOlSSdLs2bMVExOTZI7cn376SQ0bNpQkTZo0SatXr9bPP/+sQYMGSbr4gWgAAADwTkyPAAAAAK+wePFiNW/eXLVr19ann36qdOnSXXHdChUqKEeOHJKke++9V40aNdLEiRPVqVMn3XXXXe7bRo0apapVqya7j/Dw8Ouq63qnIMiRI4cyZMigKVOmXPH2BI0aNVKePHk0depUNWrUSFOnTlWVKlWSzKU7Z84cBQYG6ssvv1RQUJB7+YIFC66rHgAAADgXoS0AAAAcb8mSJWrevLlq1qypBQsWKH369Ne9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7SelMWPGqGzZstq9e7enS/GIOXPmqF27dqpatapefPFFLVq0yH1bWvib//jjj/XMM89ow4YN7mVpoa+rmTp1qpo1a6Y333xTbdu21ZtvvpnmR6BOmDBBAwYM0JtvvqmMGTO6l6f1xzqxr776Sq+++qqeeuopLV26VPv375fL5UqTLzp+8sknev7557V161ZPl3LbTJ06VQ8++KD69++vhx9+WO+++67Onj3r6bJS1cSJEzVgwAA9//zzCgwMdC/3peN68eLFGj58uJ577jmtWbNGx48fT7PH9dVs27ZN0sXrUV95/L/44gt17dpVDRo00MSJEz1dzm0xbtw4tWzZ0idffJ05c6YaN26su+++W1WqVNGCBQt09OhRT5d1VStXrtT27ds9XcZtExkZqRYtWujuu+/WAw884BODIiZMmKD27dsrV65cSZb7ynn4gw8+UIMGDXT//ferQoUK6ty5s77//ntPl+U8BnjIrFmzrGTJkjZ27FiLj483M7O4uDgPV5W6Jk+ebNmyZbNWrVpZuXLlrGbNmvbzzz97uqxUM378eEufPr3NmTMn2dsTHve0atasWRYUFGQvvviide3a1e69917Lly+fjRw50tOlpYgvvvjCgoKCLCgoyDp27Gi//PKL+7a0+th++OGHFhISYrNnz7Zz587ZzJkzLVOmTLZnzx5Pl5ZqJk6caOnTp7e5c+eamdmJEycsOjradu/ebWfPnvVwdbfHlClTLGPGjNa6dWsrX768lShRwho3bmybNm0ys7T13PXZZ59ZQECAZciQwXr16mV//PGHp0tKdTNnzrTg4GCbNWuWnTx50kaMGGFZs2a16OhoT5eWahKO648//tjMzE6dOmXHjx+3w4cP2/nz5z1c3e3xwQcfWMaMGa1Zs2ZWuHBhK1mypLVs2dJ27dplZmnruL6amTNnmsvlsueff969LK0+hydIuB5/6qmnrEOHDuZyuezTTz/1dFmpavz48RYQEHDFa/K0bN68eRYUFGTvv/++TZo0ybp06WKZM2e2fv36OfY5bs6cOeZyuax8+fL2999/e7qcVDdlyhQLDg62119/3SIjIy1PnjzWsWNHT5eVqsaPH2+BgYFXPSbT8rl42bJlFhISYrNmzbLNmzfbokWLrHz58tagQQP76KOPPF2eoxDawiOWLFli+fLls2LFilndunVt4sSJaT64jYyMtGzZstknn3xiZmZ///235cmTx1asWJFkvbRycv7ggw8sMDDQFixYYGZmBw8etHXr1tnnn39uW7Zsca+XVvq91JkzZ6xp06b26quvupdt377dhgwZYgEBAfbee+95rrgUcOTIEXv00Uetf//+9sknn1jBggWtbdu2aTq43b59u9WoUcPGjBnjXvbvv//avffea2PHjrUZM2Zcdjx7u99//938/PysQ4cOZmb222+/Wd26da1kyZKWIUMGa9WqlX355ZcerjJ17d2718qVK2dTpkxxL5szZ441bdrUSpcubRs2bDCztPH3fujQIWvevLkNGjTIJk+ebHnz5rXu3bs79p/alLB161arXLmyjR8/3r3s6NGj1rhxY5s2bZotWLDA/RinFb/88ou5XC7r3bu3mZn9+uuv1qhRIytVqpRly5bN2rdvn+bOZZfatWuXlShRwqZPn+5eNnnyZKtfv75VrlzZdu7caWZp95o0werVq6148eLWvHlzy5Qpk/Xr1899W1o4pyVnwYIFljNnTvf1uJlZs2bN7KOPPrILFy54sLLU89FHH5nL5bLPPvvMzC7+/X/00Uf2xhtv2Oeff24xMTEerjB1JPwNt2vXzp588skkt40fP94KFy5svXv3dtwL77/88otFRETY888/bxEREVauXLk0Hdx+8803li9fPps9e7Z72XvvvWcvvvii7du3z8z+OxenlfPS559/bi6Xyx1O/vHHHzZ48GB79NFHrUePHrZu3bo0ez5K8Pbbb1utWrWSLPv111/tgQcesHr16tkXX3zhocqch9AWt925c+dswIAB7pF5rVq1sho1aqTp4Pbw4cPWpk0be/PNN5Msr1Wrlj355JPWtWvXy27zZocOHbI77rjDSpcubWYXn4gqVKhg5cuXN5fLZRUqVEjyj0FadOrUKStSpIi99NJLSZYfOXLEXnnlFcuWLZtXj3Y4c+aMzZs3z7799lszM1u6dGmywW1aEhUVZbNmzXJfQJqZPfjgg5YtWzZr0KCBVa1a1UqWLJmmLjJ27dpl/fr1s5w5c9rLL79sZcuWtW7dutmCBQvso48+sgcffNCqV69u69at83SpqWb79u2WLVs2W7x4cZLl33//vT3wwANWs2ZN++uvvzxUXco6deqUzZo1y7777jszuxhOp/Xg9q+//rJp06bZ/v373csSjutq1apZ5cqVrWzZsmkqxPzjjz/sySeftFy5ctn7779vZcuWtaeeespmz55to0ePtoYNG1rdunWTvMCa1vz666+WPXt2++GHH5Is//rrr61evXp277332sGDBz1U3e1x/vx5GzVqlD355JO2bds2mzVrlqVLly5NB7enTp2yDh062Ouvv56ktypVqliDBg2sbNmy9uyzz7rfRZEW/PPPP1alShUrW7as/f777/bnn39ahQoVLCIiwkqWLGl+fn7Wvn172717t6dLTXEJj3Hz5s3dozYTB9QTJkyw7Nmz24QJE8zMOf9/Llu2zHr27Glbt261o0eP2p133nnV4Nabj9O4uDgbM2aMvfrqq3bmzBn38jp16tgdd9xhYWFhVqtWLRs1alSaeRdIbGysDRw40IoVK2bvvfeebdiwwUqWLGn33XefPfLII1akSBGLiIiwjz/+2Ksf22sZNmyYVaxY0c6cOWPx8fEWGxtrZhcHjNSqVcseeeQRO336tIerdAZCW3jE9u3bbfny5WZ2MdB85JFH3MFtck+Y3n7COnv2rK1atco9csPs4qv64eHh1qdPH+vUqZPly5fP+vbt67kiU9CFCxds8eLFlitXLqtdu7aVK1fO+vbta5s3b7bt27fb66+/bkWLFk0yYjEt6tq1qz300ENJQj6zi+Ff27Zt7ZFHHvHqt5dfWvuSJUsuC26PHz9uq1ev9kR5qeLkyZPu74cPH27h4eH222+/mZnZjh07rF69etarVy+vP2cltn//fuvfv7+lS5fOunTp4r6oMjP74YcfLH/+/PbBBx94sMLUdejQIbvrrrts+PDhlz0/ffnll3bXXXe5R86nhcf933//TfLz7NmzLwtujx8/nuZCjQRDhw61sLAw27x5s5mZbd682WrWrGkvvviimaWNx9jMbOfOndalSxdzuVzWrVu3JMf14sWLLV++fElGIqY1e/bssXLlytnEiRMvuy0yMtIqVarkvi2tPObJ2bVrlzu4jouLsxkzZlwW3JpZkr8Pb/fXX3+5n7fNzJo2bWr58uWzt99+28aPH2/ZsmWzdu3aea7AVPDTTz/Zvffea7Vq1bKwsDDr16+fRUVFmZnZ8uXL3VN5pVUvvvii5ciRw44dO2ZmSYPbl156ybJnz26HDh3yVHmXOXfunG3bts3988GDB93BbeIXic+ePZsmRmOeOXMmSV+tWrWy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WbNm9sADD6S588+VzjHnzp2zpk2bWuvWrdPEeWjOnDnmcrmsfPnyyb6DYefOnda9e3dzuVz2xBNP2DPPPOOeY9wXrr2uh8ssDQzzQppgZjp37pzq1asnM9OqVasUEBDgHumUFl24cEH79u3TM888o/379+unn35SQECA+5XvtObChQvau3evnnnmGUVHR+uHH37w+sd26dKl6tixozJkyKB8+fKpTZs26ty5s3vkQsLIu1GjRmnhwoVaunSpypUrpwwZMuj7779XYGCge3RHWhATE6PmzZtr48aN2rt3r08cw1OmTNFnn33m/psODAxM06OzLly4oAkTJmjBggU6duyY1q5dmyZ6/vLLL/XII49Ikh577DH16tXLPboy8Qishx56SLt27dLu3btVvHhxxcbGat26dQoMDEyz5+6zZ8+qSZMm+vPPP7V79+40f1yfP39e06dP14IFC3Tw4EH9+OOPaeJv/GpiYmL0wQcfaP78+Tp8+LB+/vnnNNHz559/rpYtWyowMFBPPfWUunXrpuLFi0v677g+duyYmjZtqhMnTujgwYMqXLiwYmJitH79+jR9XF/NsWPH1LBhQ8XHx7uvTdPyMX/27Flt2bJFQ4cO1Y4dO7Rp06Y0fT0uXez5t99+0yuvvKLdu3drw4YNXt3zmjVr1KFDB5UuXVpLly7V008/rbffflvSf6Pr4+Pj9ccff+itt97Sd999p2zZsilPnjyaP3++V5zvjh8/rkaNGun06dPavHlzmj4uz5w5o8WLF2vq1KnauXOnNmzYkOb+Z7rUv//+q6+//lrTpk3Trl27tHHjRq/vefPmzerYsaPq16+vZcuW6fz581qwYEGyo6Y//fRTzZo1S3FxccqTJ49GjhzpFcfl7UBoi1RzM0/6zzzzjD766CMdOnRIgYGBXvdEdCM9x8fH66OPPtKnn36qI0eO6Ntvv/W6E9ON9jtjxgzNmTNH//zzj1auXOl1/V4qJiZGQ4YMUXR0tHr16qXXXntN+/btU7t27ZINbk+cOKF9+/YpICBARYsWlZ+fn6P/xi+9SLjex/uHH35Q5cqVvfIYvpmely5dqg0bNqhv375eeQF9Mz0vXLhQP/30k1588UWv7PlSR48e1TPPPKOCBQvqrrvuUt++fVW7dm317dvXHdxeuHDB/fbJtWvXateuXcqcObPuu+8++fv7e83v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HEnPvtHz9QgICFDt2rV1//3369ChQxoyZIhefPFFtW7dWlWqVFH27Nn1+uuv69NPP02yndOP62tJ/Jh++eWXGj9+vNavX69///33mtslXKv8+uuvkrwnzKNn3+j5SuLj4xUUFKRnn31WISEh+uSTT9SiRQu1bdtWGTNmVPHixVWvXj1FR0d79IPWEs4t69at05YtWzRlyhRFRERcdRszcwdYCxcu1OnTp70m0PK1fiXf7PlKEv7fb9asmfLmzasffvhBFSpUcE83FB4ervbt2+uhhx5SpkyZPFlq2pXaQ3nhXRK/9W7OnDnWrVs3S58+vRUvXty++uor922Xvg0v8c8jRoywpk2b2j///JP6BacAX+vZ1/q9UWfOnLHq1avb22+/bWYX++7QoYOtW7fuuj8MxpMSP04ffvihZc+e3T766CMbNWqUPf7445YuXTqbO3eumSV9y0ri7SZMmGBBQUE2e/bs21f4LaBn3+j5Rv39999WunRp91ssDx06ZP369bMff/zR695C+uOPP1qHDh2sbNmy7remxcXF2ZtvvmnVqlWzLl26JPsW+sSP98SJEy0gIMBrPgSCnn2j5xu1ZcsWK1OmjK1atcrMzKKiomzAgAG2dOlSrzuur9fzzz9vISEhVrx4ccuQIYO98MILtn379mTXTfy3MH78eCtevLj9+eeft6vUFEPPvtHz1cTGxlrNmjXt0UcfNTOzs2fP2sMPP2zTp093r3O7r8sTX09FRkbanXfeaUWKFLFNmzZdtZ5LH6+goCD3OczJfK1fM9/s+Ub17dvX8ubNa2Zm//77rzVr1syGDh3qvp0pEVIeoS2S9dxzz1m+fPnsvffeswEDBlhERISVKlXKPvvsM/c6yc2jOGHCBAsJCbGPPvrottd8q3ytZ1/r93qdO3fOateubVWrVrXBgwdbnTp1rFy5cu4naW95Ilq0aJF169bNxo0b51524cIF69+/vwUGBtpvv/3mXn7phUZISIjNmzfvttabEuj5orTe8/X6+++/LWPGjPbcc8/ZwoULrXHjxnbPPfe4b/e2gGf9+vXWrl07K1269HUFemnh8aZn3+jZ7Po/7X7Tpk0WGBhob775pi1fvtyaNGliDRo0cN/ubcd1chL/Ln788UerW7eurVmzxuLj42306NFWvHhx692792WB3qV/C8HBwfbJJ5/ctrpvBT37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",
      "text/plain": [
       "<Figure size 1400x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 构建DataFrame\n",
    "df = pd.DataFrame({\n",
    "    'index': metrics,\n",
    "    'BGE-M3': [scores_m3[m] for m in metrics],\n",
    "    'BGE-M3-Finetuned': [scores_reranker[m] for m in metrics]\n",
    "})\n",
    "\n",
    "# 可视化\n",
    "plt.figure(figsize=(14, 6))\n",
    "bar_width = 0.35\n",
    "x = range(len(metrics))\n",
    "\n",
    "plt.bar(x, df['BGE-M3'], width=bar_width, label='BGE-M3')\n",
    "plt.bar([i + bar_width for i in x], df['BGE-M3-Finetuned'], width=bar_width, label='BGE-M3-Finetuned')\n",
    "\n",
    "plt.xticks([i + bar_width / 2 for i in x], df['index'], rotation=45)\n",
    "plt.ylabel('score')\n",
    "plt.title('T2Retrieval')\n",
    "plt.legend()\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "train_code_embedding",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
